﻿using BadOCR.Common;
using BadOCR.Runtime;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using HtmlAgilityPack;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BadOCR.UserControls
{
    /// <summary>
    /// YoudaoTranslatorUserControl.xaml 的交互逻辑
    /// </summary>
    public partial class YoudaoTranslatorUserControl : UserControl
    {
        private YoudaoTranslatorUserControlViewModel _viewModel;
        public YoudaoTranslatorUserControl()
        {
            InitializeComponent();

            _viewModel = new YoudaoTranslatorUserControlViewModel();
            DataContext = _viewModel;
        }

        public async void Translate(string originalText, LanguageKind targetLanguage)
        {
            _viewModel.Translating = true;
            _viewModel.Checked = false;

            var targetText = await GeneralTranslate(originalText, targetLanguage);

            _viewModel.TargetText = targetText?.Trim();
            content_control.UpdateLayout();

            _viewModel.Checked = true;
            _viewModel.Translating = false;
        }

        /// <summary>
        /// 有道词典翻译
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private async Task<string> DictTranslate(string text, LanguageKind targetLanguage)
        {
            return await Task.Run(() =>
            {
                var html = $"https://dict.youdao.com/w/{text}";
                HtmlWeb web = new HtmlWeb();
                var rootNode = web.Load(html).DocumentNode;

                try
                {
                    var ydTransNode = rootNode.SelectSingleNode("//div[@id='ydTrans']");
                    if (ydTransNode != null)
                    {
                        return rootNode.SelectSingleNode("//div[@id='fanyiToggle']/div/p[2]")?.InnerText;
                    }
                    else
                    {
                        var sb = new StringBuilder();

                        // 中 -> 英 时候的排版格式
                        var liNodes = rootNode.SelectNodes("//div[@id='phrsListTab']/div[contains(@class, 'trans-container')]/ul/li");
                        if (liNodes != null)
                        {
                            foreach (var liNode in liNodes)
                            {
                                var translationItemText = liNode.InnerText;
                                var ks = translationItemText.Split(new char[] { ' ' });

                                var kind = ks.Count() >= 1 ? ks[0] : string.Empty;
                                var translation = ks.Count() >= 2 ? ks[1] : string.Empty;
                                sb.AppendLine($"{kind} {translation}");
                            }
                        }
                        // 英 -> 中 时候的排版格式
                        else
                        {
                            var pNodes = rootNode.SelectNodes("//div[@id='phrsListTab']/div[contains(@class, 'trans-container')]/ul/p");
                            foreach (var pNode in pNodes)
                            {
                                var kind = pNode.SelectSingleNode("./span[not(@class='contentTitle')]")?.InnerText;

                                var translation = new StringBuilder();
                                foreach (var aNode in pNode.SelectNodes("./span[@class='contentTitle']/a"))
                                    translation.Append($"{aNode.InnerText?.Trim()};");
                                sb.AppendLine($"{kind} {translation}");
                            }
                        }

                        return sb.ToString();
                    }
                }
                catch
                {
                    return "暂无搜索结果";
                }
            });
        }

        /// <summary>
        /// https://zhuanlan.zhihu.com/p/350310930
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private async Task<string> GeneralTranslate(string text, LanguageKind targetLanguage)
        {
            return await Task.Run(() =>
            {
                try
                {
                    // 计算关键参数
                    var ts = DateTime.Now.ToTimeStamp().ToString();
                    var randomNum = new Random().Next(0, 10).ToString();
                    var salt = ts + randomNum;
                    var sign = Md5("fanyideskweb" + text + salt + "Tbh5E8=q6U3EXe+&L[4c@");

                    // 请求体
                    var requestParamsDict = new Dictionary<string, string>();
                    requestParamsDict.Add("i", text);
                    requestParamsDict.Add("from", "AUTO");
                    requestParamsDict.Add("to", GetLanguageCode(targetLanguage));
                    requestParamsDict.Add("smartresult", "dict");
                    requestParamsDict.Add("client", "fanyideskweb");

                    requestParamsDict.Add("salt", salt);
                    requestParamsDict.Add("sign", sign);
                    //requestParamsDict.Add("", "");
                    //requestParamsDict.Add("", "");
                    //requestParamsDict.Add("", "");

                    requestParamsDict.Add("version", "2.1");
                    requestParamsDict.Add("keyfrom", "fanyi.web");
                    requestParamsDict.Add("action", "FY_BY_REALTlME");

                    // 请求头
                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule");
                    req.Headers.Add(HttpRequestHeader.Cookie, "OUTFOX_SEARCH_USER_ID=-1927650476@223.97.13.65;");
                    req.Host = "fanyi.youdao.com";
                    req.Headers.Add("Origin", "http://fanyi.youdao.com");
                    req.Referer = "http://fanyi.youdao.com/";
                    req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36";

                    // 发起请求
                    req.Method = "POST";
                    req.ContentType = "application/x-www-form-urlencoded";

                    StringBuilder builder = new StringBuilder();
                    int i = 0;
                    foreach (var requestParam in requestParamsDict)
                    {
                        if (i > 0)
                            builder.Append("&");
                        builder.AppendFormat("{0}={1}", requestParam.Key, requestParam.Value);
                        i++;
                    }
                    byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
                    req.ContentLength = data.Length;
                    using (Stream reqStream = req.GetRequestStream())
                    {
                        reqStream.Write(data, 0, data.Length);
                        reqStream.Close();
                    }

                    HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                    Stream stream = resp.GetResponseStream();

                    using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                    {
                        var response = JToken.Parse(reader.ReadToEnd());
                        return response["translateResult"][0][0]["tgt"].ToString();
                    }
                }
                catch
                {
                    return "暂无搜索结果";
                }
            });
        }

        /// <summary>
        /// 备用
        /// </summary>
        /// <returns></returns>
        private string Translate3()
        {
            // http://fanyi.youdao.com/translate?&type=ZH_CN2JA&i=苹果&doctype=json
            return "";
        }

        private string Md5(string str)
        {
            var sb = new StringBuilder();
            MD5 md5 = MD5.Create();
            byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
            for (int i = 0; i < s.Length; i++)
            {
                // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符
                //pwd = pwd + s[i].ToString("X");
                sb.Append(s[i].ToString("x2"));
            }
            return sb.ToString();
        }

        private string GetLanguageCode(LanguageKind languageKind)
        {
            switch (languageKind)
            {
                case LanguageKind.SimplifiedChinese:
                    return "zh-CHS";
                case LanguageKind.Japanese:
                    return "ja";
                case LanguageKind.Korean:
                    return "ko";
                case LanguageKind.English:
                    return "en";
            }

            return string.Empty;
        }
    }

    public class YoudaoTranslatorUserControlViewModel : ViewModelBase
    {
        #region BindingProperty
        private bool _translating;
        public bool Translating
        {
            get => _translating;
            set
            {
                _translating = value;
                RaisePropertyChanged(nameof(Translating));
            }
        }

        private string _targetText;
        public string TargetText
        {
            get => _targetText;
            set
            {
                _targetText = value;
                RaisePropertyChanged(nameof(TargetText));
            }
        }

        private bool _checked;
        public bool Checked
        {
            get => _checked;
            set
            {
                _checked = value;
                RaisePropertyChanged(nameof(Checked));
            }
        }
        #endregion

        #region BindingCommand
        private RelayCommand _copyCommand;
        public ICommand CopyCommand
        {
            get
            {
                if (_copyCommand == null)
                    _copyCommand = new RelayCommand(() => Copy());

                return _copyCommand;
            }
        }

        private void Copy()
        {
            ClipboardHelper.SetText(TargetText);
        }
        #endregion
    }
}
